package com.lee.service.impl;

import cn.hutool.core.util.IdUtil;
import com.lee.common.AppResult;
import com.lee.common.PromptModel;
import com.lee.service.AbstractService;
import com.lee.service.SSEService;
import com.volcengine.ark.runtime.model.completion.chat.ChatCompletionRequest;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.volcengine.ark.runtime.service.ArkService;
import io.reactivex.schedulers.Schedulers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class AbstractServiceImpl implements AbstractService {
    @Autowired
    private ArkService service;
    @Autowired
    private SSEService sseService;

    @Override
    public AppResult getAbstract(Long id) {
        // todo
        // 这里是调用数据库查询逻辑
        return null;
    }

    @Override
    public AppResult generateAbstract(Long id) {
        // 0.获取用户id
        Long userId = 001l;
        // 1.根据id查询帖子
        String content = "## 引言\n" +
                "无论你是刚入门的程序小白，还是混迹社会多年的程序大佬，谈起面向对象，想必多多少少都能侃上两句。面向对象作为程序界“家喻户晓”的一种编程思想，亦或是一种程序设计方法，重要性已是不言而喻。毫不夸张的说，程序界不能失去面向对象，就像西方不能失去耶路撒冷！！！\n" +
                "\n" +
                "这篇文章我会阐述一下笔者个人对于“面向对象”的理解，我会尽量使用最简洁的语言，从不同的角度进行论述。\n" +
                "\n" +
                "当你打开百度搜索词条“面向对象”，你经常会看到类似这样一段话：\n" +
                "\n" +
                "> “面向对象是一种程序设计方法，或者说它是一种程序设计规范，其基本思想是使用对象、类、继承、封装、多态、消息等基本概念来进行程序设计。所谓“面向对象”就是以对象及其行为为中心，来考虑处理问题的思想体系和方法。采用面向对象方法设计的软件，不仅易于理解，而且易于维护和修改，从而提高了软件的可靠性和可维护性，同时也提高了软件模块化和可重用化的程度。”\n" +
                "\n" +
                "没有任何问题，这就是面向对象的定义，但是概念往往都是抽象的，看完之后你肯定会有类似这些疑问：\n" +
                "1. 说了个寂寞，到底什么是面向对象？\n" +
                "2. 为什么需要对象、类、继承、封装、多态、消息等基本概念？\n" +
                "3. 面向对象这些优势如何体现？\n" +
                "\n" +
                "这些问题也是我遇到过的，下面我我站在我的视角上替大家翻译翻译：\n" +
                "\n" +
                "## 一、什么是面向对象？\n" +
                "面向对象给我们解决问题提供了一种思路，就是将问题模块化，划分为一个个的对象，可以让我们用聚少成多的方法来写程序。\n" +
                "\n" +
                "谈到面向对象这种思想，我们通常会想到面向过程，举个例子，比如洗衣服：\n" +
                "如果使用面向过程，洗衣服大概是这样的。首先我们打来一盆水，然后放入脏衣服、洗衣粉，接下来便是手搓、拧干、晾晒。可见整个过程不仅麻烦，还是单线程的，费时费力。\n" +
                "\n" +
                "如果是使用面向对象，洗衣服只需三步。第一步准备好脏衣服、洗衣粉，第二步放入全自动洗衣机并启动，第三步收衣服。整个过程完全不必在意洗衣细节，而且还支持多线程，洗衣期间可能还能做点别的事，真的是太优雅了。\n" +
                "## 二、对象、类、继承、封装、多态、消息等基本概念有什么用？\n" +
                "**类（Class）**：类可以看作是对象的蓝图或模具，用于创建具体的对象实例。它定义了一组具有相似属性和行为的对象的模板。比如上面的洗衣机的生产通常需要依赖工程师提供的图纸，而这里的类就相当于是那张图纸。\n" +
                "\n" +
                "**对象（Object）**：对象是类的一个实例，它具有类定义的属性和行为。换句话说，对象是类的具体实体，代表了现实世界中的某个具体事物。比如我们上面使用的洗衣机实体就是一个对象。\n" +
                "\n" +
                "**封装（Encapsulation）**：封装是将数据（属性）和行为（方法）封装在对象内部，并对外部隐藏其内部实现细节的过程。通过封装，可以实现信息隐藏和保护对象的数据完整性，同时提供简单的接口供外部访问。比如洗衣机就是将洗衣流程封装起来，只给用户预留了一些可用的开关。\n" +
                "\n" +
                "**继承（Inheritance）**：继承是一种机制，允许一个类（子类）从另一个类（父类）中继承属性和行为。通过继承，子类可以重用父类的代码，并且可以在不修改父类的情况下添加新的功能或修改现有功能。\n" +
                "\n" +
                "**多态（Polymorphism）**：多态是指同一个方法调用可以根据调用对象的不同而表现出不同的行为。通过多态，可以提高代码的灵活性和可扩展性，使得程序可以处理不同类型的对象而不需要编写大量的条件语句。\n" +
                "\n" +
                "**消息（Message）**：在面向对象编程中，对象之间的交互是通过发送消息实现的。这个消息可能是包含了要执行的方法和相关的参数，接收消息的对象根据接收到的消息调用相应的方法进行处理。\n" +
                "## 三、面向对象这些优势如何体现？\n" +
                "面向对象的一个最大的优势就是“==可维护性复用==”，想要实现这一点，需要我们在设计时遵循一些指导性的设计原则：\n" +
                "\n" +
                "![](https://i-blog.csdnimg.cn/blog_migrate/364b8a3a3db59ffdbb98acc123e4787c.png)\n" +
                "\n";
        // 2.调用prompt模板并填充完整
        String finalPrompt = PromptModel.ABSTRACT_PROMOT_MODEL.replace("{{DOCUMENT}}", content);
        // 3.调用DouBao异步生成帖子摘要
        final List<ChatMessage> streamMessages = new ArrayList<>();
        final ChatMessage streamSystemMessage = ChatMessage.builder().role(ChatMessageRole.SYSTEM)
                .content("你是豆包，是由字节跳动开发的 AI 人工智能助手").build();
        final ChatMessage streamUserMessage = ChatMessage.builder().role(ChatMessageRole.USER)
                .content(finalPrompt).build();
        streamMessages.add(streamSystemMessage);
        streamMessages.add(streamUserMessage);
        ChatCompletionRequest streamChatCompletionRequest = ChatCompletionRequest.builder()
                .model("ep-20250207210413-l6c9q")
                .messages(streamMessages)
                .build();

        service.streamChatCompletion(streamChatCompletionRequest)
                .doOnError(Throwable::printStackTrace)
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.single())
                .subscribe(
                        choice -> {
                            if (choice.getChoices().size() > 0) {
                                sseService.sendMessage("1",
                                        "消息"+ IdUtil.fastUUID().replace("-",""),
                                        choice.getChoices().get(0).getMessage().getContent()+"");
//                                System.out.print(choice.getChoices().get(0).getMessage().getContent());
                            }
                        },
                        error -> {
                            error.printStackTrace();
                        },
                        () -> {
                            // 4.将生成结果写入数据库
                            System.out.println("========= 输出完成 ==========");
                        }
                );

        // 5.返回结果
        return null;
    }
}
